package com.cavy.platform.server.service;

import com.cavy.platform.server.domain.job.ContainerLogSubscribeKey;
import com.cavy.platform.server.domain.job.ContainerLogUnSubscribeKey;
import com.cavy.platform.server.repository.JobLogRepository;
import org.apache.commons.io.input.Tailer;
import org.apache.commons.io.input.TailerListenerAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PreDestroy;
import java.io.File;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
import java.util.function.Function;

@Service
public class ContainerLogTailerManager {
    @Autowired
    private JobLogRepository logRepository;
    @Autowired
    private JobSubscribe subscribe;
    private ConcurrentHashMap<ContainerLogSubscribeKey, Tailer> tailerMap = new ConcurrentHashMap<>();

    //创建一个tailer
    public void create(ContainerLogSubscribeKey key) {
        File file = logRepository.load(key);
        if (file == null) {
            return;
        }
        ContainerLogTialer logTialer = new ContainerLogTialer(key);
        tailerMap.computeIfAbsent(key, new Function<ContainerLogSubscribeKey, Tailer>() {
            @Override
            public Tailer apply(ContainerLogSubscribeKey key) {
                return Tailer.create(file, logTialer);
            }
        });
    }

    //销毁tailer
    public void destroy(ContainerLogUnSubscribeKey key) {
        key.setType(ContainerLogSubscribeKey.DEFAULT_TYPE);
        Tailer tailer = tailerMap.get(key);
        if (tailer != null) {
            tailer.stop();
        }
    }

    @PreDestroy
    public void destroy() {
        tailerMap.values().forEach(new Consumer<Tailer>() {
            @Override
            public void accept(Tailer tailer) {
                tailer.stop();
            }
        });
    }

    private class ContainerLogTialer extends TailerListenerAdapter {

        private ContainerLogSubscribeKey key;

        public ContainerLogTialer(ContainerLogSubscribeKey key) {
            this.key = key;
        }

        @Override
        public void handle(String s) {
            subscribe.send(s, key);
        }
    }
}
